﻿using System.Drawing;
using System.Drawing.Drawing2D;
using GraphDrawing2.Canvas;
using GraphDrawing2.Core;

namespace GraphDrawing2.V2.Graph.Model
{
    public class ConnectableElementView : IConnectableElementView
    {
        readonly GraphicsPath interior;
        readonly ConnectorView inputConnectorView;
        readonly ConnectorView outputConnectorView;
        readonly Appearance standard;
        readonly Appearance hovered;
        readonly Appearance selected;

        ConnectableElementModel model;

        public ConnectableElementView()
        {
            interior = new GraphicsPath();
            inputConnectorView = new ConnectorView();
            outputConnectorView = new ConnectorView();
            standard = new Appearance();
            hovered = new Appearance();
            selected = new Appearance();
            hovered.Border.Width = 2f;
            selected.CopyFrom(hovered);
            selected.Border.Color = Color.DodgerBlue;
        }

        public void Initialize(ConnectableElementModel model)
        {
            this.model = model;
            inputConnectorView.Initialize(model.InputConnector);
            outputConnectorView.Initialize(model.OutputConnector);
            interior.AddRectangle(new RectangleF(0, 0, model.Width, model.Height));
        }

        public bool Contains(PointF p)
        {
            return interior.IsVisible(p);
        }

        public bool IsInputHit(PointF p)
        {
            return inputConnectorView.Contains(p);
        }

        public bool IsOutputHit(PointF p)
        {
            return outputConnectorView.Contains(p);
        }

        public void Render(DrawingContext dc)
        {
            var g = dc.graphics;
            using (g.DrawLocal())
            {
                g.TranslateTransform(model.Position.X, model.Position.Y);
                var appearance = GetAppearance();
                using (var brush = appearance.CreateBrush())
                    g.FillPath(brush, interior);
                using (var pen = appearance.Border.CreatePen())
                    g.DrawPath(pen, interior);
                inputConnectorView.Render(dc);
                outputConnectorView.Render(dc);
            }
        }

        Appearance GetAppearance()
        {
            if (model.IsSelected())
                return selected;
            if (model.IsHovered())
                return hovered;
            return standard;
        }
    }
}